package edu.ust.seis610.data;

import java.io.File;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import edu.ust.seis610.data.DataPoint;

/**
 * @author m042872
 *
 */
public class TrainingData 
{
	
	public static void createInitialXMLFile()
	{
		try
		{
			  DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
			  DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
		 
			  //root elements
			  Document doc = docBuilder.newDocument();
			  Element rootElement = doc.createElement("TrainingData");
			  doc.appendChild(rootElement);
		 
//			  this loop runs from 1-500 and generates all the training data needed.
//			  TODO change this to a double so that the xml file is consistent (X's and Y's should both have decimal points and be in double format)
			  for(double ix=1;ix<=500;ix++)
			  {
				  //DataPoint elements
				  Element dataPoint = doc.createElement("DataPoint");
				  rootElement.appendChild(dataPoint);
			 
				  //x elements
				  Element x = doc.createElement("X");
				  x.appendChild(doc.createTextNode(Double.toString(ix)));
				  dataPoint.appendChild(x);
			 
				  //y elements
				  Element y = doc.createElement("Y");
				  y.appendChild(doc.createTextNode(evaluateTrainingFunction(ix)));
				  dataPoint.appendChild(y);
			  }
			  //write the content into xml file
			  TransformerFactory transformerFactory = TransformerFactory.newInstance();
			  Transformer transformer = transformerFactory.newTransformer();
			  DOMSource source = new DOMSource(doc);
			  StreamResult result =  new StreamResult(new File("training_data.xml"));
			  transformer.transform(source, result);	
			  
		}
		catch(Exception e)
		{
			System.out.println(e.getMessage());
		}
	}
	
	public static ArrayList<DataPoint> getTrainingData()
	{
		ArrayList<DataPoint> dps = new ArrayList<DataPoint>();
		
		try {
			 
		    File fXmlFile = new File("training_data.xml");
		    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
		    DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
		    Document doc = dBuilder.parse(fXmlFile);
		    doc.getDocumentElement().normalize();
		 
		    NodeList nList = doc.getElementsByTagName("DataPoint");
		 
		    for (int temp = 0; temp < nList.getLength(); temp++) {
		 
		       Node nNode = nList.item(temp);	    
		       if (nNode.getNodeType() == Node.ELEMENT_NODE) 
		       {
		          DataPoint dp = new DataPoint();
		          
		    	  Element eElement = (Element) nNode;
		          dp.setX(Double.parseDouble(getTagValue("X",eElement)));
		    	  dp.setY(Double.parseDouble(getTagValue("Y",eElement)));
		    	  dps.add(dp);
		        }
		    }
		  } 
		catch (Exception e) 
		{
		    e.printStackTrace();
		}
		return dps;
	}
	
	private static String getTagValue(String sTag, Element eElement)
	{
	    NodeList nlList= eElement.getElementsByTagName(sTag).item(0).getChildNodes();
	    Node nValue = (Node) nlList.item(0); 
		 
	    return nValue.getNodeValue();    
	}
	
//	this evaluates the input x values and solves for f(x)=(x^2-1)/2
	private static String evaluateTrainingFunction(double x)
	{
		String tmp;
		double y = ((x*x)+1)/2;
		tmp=Double.toString(y);
		
		return tmp;
	}
	
}
